// --------------------------------------------------------------------------------------------------------------------
// <copyright file="RuntimeCounterManager.cs" company="Microsoft Corporation">
// The MIT License (MIT)
// 
// Copyright (c) 2014, Microsoft Corporation
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------
namespace Microsoft.Robotics.PerformanceCounters
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Security;
    using Microsoft.Robotics.Tracing;

    /// <summary>
    /// The counters we support
    /// </summary>
    public enum RuntimeCounters
    {
        /// <summary>
        /// The rate of dropped messages, per agent/message type
        /// </summary>
        DroppedMessages,

        /// <summary>
        /// The rate of processed messages, per agent/message type
        /// </summary>
        ProcessedMessages,

        /// <summary>
        /// The time it took to process the message, per agent/message type
        /// </summary>
        ProcessingTime,

        /// <summary>
        /// The time spent by messages waiting in the delivery queue
        /// </summary>
        DelayTime,

        /// <summary>
        /// The number of messages in the queue
        /// </summary>
        QueueSize,
    }

    /// <summary>
    /// Provides methods for creating and updating the performance counters
    /// </summary>
    public static class RuntimeCounterManager
    {
        /// <summary>
        /// The name of the counter group
        /// </summary>
        private static readonly string CategoryName = "Microsoft Robotics Runtime";

        /// <summary>
        /// Installs the performance counters
        /// </summary>
        /// <param name="installCounters">If true, the counters are recreated (requires admin permissions)</param>
        public static void Setup(bool installCounters)
        {
            Dictionary<int, CounterCreationData> counterDefinitions = new Dictionary<int, CounterCreationData>();
            counterDefinitions[(int)RuntimeCounters.DroppedMessages] = new CounterCreationData("Dropped messages / second", "Number of messages dropped per second", PerformanceCounterType.RateOfCountsPerSecond32);
            counterDefinitions[(int)RuntimeCounters.ProcessedMessages] = new CounterCreationData("Messages / second", "Number of messages processed per second", PerformanceCounterType.RateOfCountsPerSecond32);
            counterDefinitions[(int)RuntimeCounters.ProcessingTime] = new CounterCreationData("Processing time", "The time it takes to process the latest message", PerformanceCounterType.NumberOfItems32);
            counterDefinitions[(int)RuntimeCounters.DelayTime] = new CounterCreationData("Delay time", "The time spent by messages waiting in the delivery queue", PerformanceCounterType.NumberOfItems32);
            counterDefinitions[(int)RuntimeCounters.QueueSize] = new CounterCreationData("Queue size", "The number of messages waiting in the delivery queue", PerformanceCounterType.NumberOfItems32);

            PerformanceCounterManager.SetupCounters(CategoryName, counterDefinitions, installCounters);
        }

        /// <summary>
        /// Creates all the counters for the specified instance.
        /// </summary>
        /// <param name="instanceName">The name of the instance (agent name + message type)</param>
        /// <returns>The counters for the specified instance</returns>
        public static Dictionary<RuntimeCounters, PerformanceCounter> AddInstance(string instanceName)
        {
            return PerformanceCounterManager.AddInstance<RuntimeCounters>(CategoryName, instanceName);
        }

        /// <summary>
        /// Retrieves a counter based on instance name and counter name
        /// </summary>
        /// <param name="instanceName">The name of the counter instance</param>
        /// <returns>The counters for the specified instance</returns>
        public static Dictionary<RuntimeCounters, PerformanceCounter> GetCounters(string instanceName)
        {
            return PerformanceCounterManager.GetCounters<RuntimeCounters>(CategoryName, instanceName);
        }
    }
}
